using System.Diagnostics;
using Bitcoin.Cryptography;

namespace Bitcoin
{
    // TODO: Fold this class into the TransactionInput class. It's not necessary.

    /// <summary>
    ///     This message is a reference or pointer to an output of a different transaction.
    /// </summary>
    //[Serializable]
    public class TransactionOutPoint
    {
        internal TransactionOutPoint(int index, Transaction fromTx)
        {
            Index = index;
            if (fromTx != null)
            {
                Hash = fromTx.Hash;
                FromTx = fromTx;
            }
            else
            {
                // This happens when constructing the genesis block.
                Hash = Sha256Hash.ZeroHash;
            }
        }

        public TransactionOutPoint(byte[] hashBytes, uint index)
        {
            Hash = new Sha256Hash(hashBytes);
            Index = (int) index;
        }

        /// <summary>
        ///     If this transaction was created using the explicit constructor rather than deserialized,
        ///     retrieves the connected output transaction. Asserts if there is no connected transaction.
        /// </summary>
        public TransactionOutput ConnectedOutput
        {
            get { return FromTx != null ? FromTx.Outputs[Index] : null; }
        }

        /// <summary>
        ///     Convenience method to get the connected outputs pubkey hash.
        /// </summary>
        /// <exception cref="ScriptException" />
        public byte[] ConnectedPubKeyHash
        {
            get { return ConnectedOutput.ScriptPubKey.PubKeyHash; }
        }

        /// <summary>
        ///     Returns the pubkey script from the connected output.
        /// </summary>
        public byte[] ConnectedPubKeyScript
        {
            get
            {
                var result = ConnectedOutput.ScriptBytes;
                Debug.Assert(result != null);
                Debug.Assert(result.Length > 0);
                return result;
            }
        }

        public Transaction FromTx { get; set; }

        /// <summary>
        ///     Which output of that transaction we are talking about.
        /// </summary>
        public int Index { get; private set; }

        public override string ToString()
        {
            return "outpoint " + Index + ":" + Hash;
        }

        /// <summary>
        ///     Hash of the transaction to which we refer.
        /// </summary>
        internal Sha256Hash Hash { get; set; }
    }
}